package com.isoftstone.storage.events;

import java.io.File;

import com.isoftstone.storage.Storage;
import com.isoftstone.storage.resource.Resource;

/**
 * 传输事件
 */
public class TransferEvent extends StorageEvent {
	private static final long serialVersionUID = 8052020282066098126L;

	/**
	 * A transfer was attempted, but has not yet commenced.
	 */
	public static final int TRANSFER_INITIATED = 0;

	/**
	 * A transfer was started.
	 */
	public static final int TRANSFER_STARTED = 1;

	/**
	 * A transfer is completed.
	 */
	public static final int TRANSFER_COMPLETED = 2;

	/**
	 * A transfer is in progress.
	 */
	public static final int TRANSFER_PROGRESS = 3;

	/**
	 * An error occurred during transfer
	 */
	public static final int TRANSFER_ERROR = 4;

	/**
	 * Indicates GET transfer (from the repository)
	 */
	public static final int REQUEST_GET = 5;

	/**
	 * Indicates PUT transfer (to the repository)
	 */
	public static final int REQUEST_PUT = 6;

	private Resource resource;

	private int eventType;

	private int requestType;

	private Exception exception;

	private File localFile;

	public TransferEvent(final Storage storage, final Resource resource,
			final int eventType, final int requestType) {
		super(storage);

		this.resource = resource;

		setEventType(eventType);

		setRequestType(requestType);

	}

	public TransferEvent(final Storage storage, final Resource resource,
			final Exception exception, final int requestType) {
		this(storage, resource, TRANSFER_ERROR, requestType);

		this.exception = exception;
	}

	public Resource getResource() {
		return resource;
	}

	public Exception getException() {
		return exception;
	}

	public int getRequestType() {
		return requestType;
	}

	public void setRequestType(final int requestType) {
		switch (requestType) {

		case REQUEST_PUT:
		case REQUEST_GET:
			break;

		default:
			throw new IllegalArgumentException("Illegal request type: "
					+ requestType);
		}

		this.requestType = requestType;
	}

	public int getEventType() {
		return eventType;
	}

	public void setEventType(final int eventType) {
		switch (eventType) {

		case TRANSFER_INITIATED:
		case TRANSFER_STARTED:
		case TRANSFER_COMPLETED:
		case TRANSFER_PROGRESS:
		case TRANSFER_ERROR:
			break;
		default:
			throw new IllegalArgumentException("Illegal event type: "
					+ eventType);
		}

		this.eventType = eventType;
	}

	public void setResource(final Resource resource) {
		this.resource = resource;
	}

	public File getLocalFile() {
		return localFile;
	}

	public void setLocalFile(File localFile) {
		this.localFile = localFile;
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();

		sb.append("TransferEvent[");

		switch (this.getRequestType()) {
		case REQUEST_GET:
			sb.append("GET");
			break;
		case REQUEST_PUT:
			sb.append("PUT");
			break;
		default:
			sb.append(this.getRequestType());
			break;
		}

		sb.append("|");
		switch (this.getEventType()) {
		case TRANSFER_COMPLETED:
			sb.append("COMPLETED");
			break;
		case TRANSFER_ERROR:
			sb.append("ERROR");
			break;
		case TRANSFER_INITIATED:
			sb.append("INITIATED");
			break;
		case TRANSFER_PROGRESS:
			sb.append("PROGRESS");
			break;
		case TRANSFER_STARTED:
			sb.append("STARTED");
			break;
		default:
			sb.append(this.getEventType());
			break;
		}

		sb.append("|");

		sb.append(this.getStorage().getRepository()).append("|");
		sb.append(this.getLocalFile()).append("|");
		sb.append(this.getResource().inspect());
		sb.append("]");

		return sb.toString();
	}

	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + eventType;
		result = prime * result
				+ ((exception == null) ? 0 : exception.hashCode());
		result = prime * result
				+ ((localFile == null) ? 0 : localFile.hashCode());
		result = prime * result + requestType;
		result = prime * result
				+ ((resource == null) ? 0 : resource.hashCode());
		return result;
	}

	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if ((obj == null) || (getClass() != obj.getClass())) {
			return false;
		}
		final TransferEvent other = (TransferEvent) obj;
		if (eventType != other.eventType) {
			return false;
		}
		if (exception == null) {
			if (other.exception != null) {
				return false;
			}
		} else if (!exception.getClass().equals(other.exception.getClass())) {
			return false;
		}
		if (requestType != other.requestType) {
			return false;
		}
		if (resource == null) {
			if (other.resource != null) {
				return false;
			}
		} else if (!resource.equals(other.resource)) {
			return false;
		} else if (!source.equals(other.source)) {
			return false;
		}
		return true;
	}

}
